package com.store.orm.mysql.reflection;

import com.store.orm.mysql.MySQLUtil;
import com.store.orm.mysql.crud.Insert;
import com.store.orm.mysql.crud.impl.MySQLInsert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * @author 宫静雨
 * @version 1.0
 */
public class InsertProxy implements InvocationHandler {
    private MySQLUtil UTIL;
    private static final Logger logger = LoggerFactory.getLogger(InsertProxy.class);

    private MySQLInsert mySQLInsert;

    public InsertProxy(MySQLInsert mySQLInsert) {
        this.mySQLInsert = mySQLInsert;
        this.UTIL = mySQLInsert.getUTIL();
    }

    public Insert proxy() {
        return (Insert) Proxy.newProxyInstance(mySQLInsert.getClass().getClassLoader(),
                new Class[]{Insert.class}, this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object invoke = method.invoke(mySQLInsert, args);

        if (method.getName().equals("insert")) {
            LinkedHashMap<String, List<Object>> map =
                    (LinkedHashMap<String, List<Object>>) invoke;
            map.forEach((k, v) -> {
                Connection connection = UTIL.getConnection();
                try {
                    PreparedStatement ps = connection.prepareStatement(k);
                    for (int i = 0; i < v.size(); i++) {
                        ps.setObject(i + 1, v.get(i));
                    }
                    int update = ps.executeUpdate();
                    if (UTIL.isLogged()) {
                        logger.info(">>> {}", k);
                        logger.info("<<< {}", v);
                        if (update == 1) {
                            logger.info("新增数据: {}", true);
                        } else {
                            logger.info("新增数据: {}", false);
                        }
                    }
                } catch (SQLException e) {
                    logger.error("执行SQL出错: {}", e.getMessage());
                }
            });
        } else if (method.getName().equals("insertMany")) {
            List<String> sqls = (List<String>) invoke;
            Connection connection = UTIL.getConnection();
            Statement statement = connection.createStatement();
            int quantity = 0;
            for (int i = 0; i < sqls.size(); i++) {
                statement.addBatch(sqls.get(i));
                if (i % UTIL.maxBatch() == 0) {
                    quantity += statement.executeBatch().length;
                    statement.clearBatch();
                }
                if (UTIL.isBatchLog()) {
                    logger.info(">>> {}", sqls.get(i));
                }
            }
            quantity += statement.executeBatch().length;
            statement.clearBatch();
            if (UTIL.isLogged()) {
                logger.info("新增数据: {}条", quantity);
            }
        }
        return null;
    }
}